<?php


namespace app\cms\admin\controller;


use app\cms\dto\formContent;
use app\cms\dto\formFieldInfo;
use app\cms\model\buildModel;
use app\cms\model\formFieldModel;
use app\cms\model\formModel;
use app\cms\model\replyModel;
use iflow\auth\Authorize\AuthAnnotation;
use iflow\Helper\Str\Str;
use iflow\Response;
use iflow\Router\Controller;
use iflow\Router\implement\Request\{ GetMapping, PostMapping, DeleteMapping };
use think\db\exception\DbException;

#[Controller('%cmsAdmin%/form')]
class form
{

    /**
     * 获取表单模型列表
     * @param string $form_name
     * @return Response
     * @throws DbException
     */
    #[GetMapping]
    #[AuthAnnotation('form', 'formReadWrite|formRead')]
    public function getForms(string $form_name = ''): Response
    {
        $query = formModel::where(['status' => 1]);
        if ($form_name !== '') {
            $query -> whereLike('form_name', "%{$form_name}%");
        }
        $query = $query -> paginate([
            'page' => request() -> getParams('page'),
            'list_rows' => 10
        ]);
        if ($query -> items()) {
            return message() -> success('查询成功', $query -> items(), [
                'count' => $query -> total(),
                'page' => $query -> lastPage()
            ]);
        }
        return message() -> nodata('暂无数据');
    }

    /**
     * 获取单个表单模型
     * @param int $form_id
     * @return Response
     */
    #[GetMapping]
    #[AuthAnnotation('form', 'formReadWrite|formRead')]
    public function getForm(int $form_id = 0): Response
    {
        $form = (new formModel) -> getForm($form_id);
        return $form ? message() -> success('获取表单模型成功', $form)
            : message() -> nodata('表单模型不存在');
    }

    /**
     * 获取绑定模型数据
     * @param int $form_id
     * @param string $keyword
     * @return Response
     */
    #[GetMapping]
    #[AuthAnnotation('form', 'formReadWrite|formRead')]
    public function getBindModelData(int $form_id, string $keyword = ""): Response
    {
        return (new formModel()) -> getBindModelData($form_id, $keyword);
    }

    /**
     * 添加表单模型
     * @param string $form_name
     * @return Response
     */
    #[PostMapping]
    #[AuthAnnotation('form', 'formReadWrite|formWrite')]
    public function addForm(string $form_name = ''): Response {
        $form_name = Str::humpToLower($form_name);
        $formModel = new formModel;

        $form = $formModel -> where([
            'form_name' => $form_name
        ]) -> findOrEmpty();
        if ($form -> isEmpty()) {
            return $formModel -> addForm($form_name);
        }
        return message() -> nodata("表模型已存在");
    }

    /**
     * 删除表单模型
     * @param int $form_id
     * @return Response
     */
    #[DeleteMapping]
    #[AuthAnnotation('form', 'formReadWrite|formWrite')]
    public function delForm(int $form_id): Response
    {
        return (new formModel) -> delForm($form_id);
    }

    /**
     * 获取表单模型列
     * @param int $form_id
     * @param string $form_field_name
     * @return Response
     */
    #[GetMapping('get_fields/<[0-9]+:form_id>')]
    #[AuthAnnotation('form', 'formReadWrite|formRead')]
    public function getFields(int $form_id, string $form_field_name = ''): Response
    {
        return (new formFieldModel) -> getFields($form_id, $form_field_name);
    }

    /**
     * 设置表单模型标题列
     * @param int $form_id
     * @param string $form_field_name
     * @return Response
     */
    #[PostMapping('set_title_field/<[0-9]{1,8}:form_id>/<[\w\W]+:form_field_name>')]
    #[AuthAnnotation('form', 'formReadWrite|formWrite')]
    public function setTitleField(int $form_id = 0, string $form_field_name = ''): Response
    {
        $field = (new formFieldModel()) -> where([
            'form_id' => $form_id,
            'form_field_name' => $form_field_name
        ]) -> findOrEmpty();

        if ($field -> isEmpty()) return message() -> nodata('表单模型或表单列不存在');

        $update = (new formModel) -> update([
            'title_field' => $form_field_name
        ], [
            'form_id' => $form_id
        ]) -> getChangedData();
        return message() -> success('设置成功', $update);
    }

    /**
     * 绑定指定模型
     * @param int $form_id
     * @param string $form_name
     * @return Response
     */
    #[PostMapping('bind_form/<[0-9]{1,8}:form_id>/<[\w\W]+:form_name>')]
    #[AuthAnnotation('form', 'formReadWrite|formWrite')]
    public function setBindForm(int $form_id = 0, string $form_name = ''): Response
    {
        $bindForm = (new formModel) -> where([
            'form_name' => $form_name
        ]) -> findOrEmpty();

        if ($bindForm -> isEmpty()) return message() -> nodata('需要绑定的模型不存在');

        $form = (new formModel) -> where([
            'form_id' => $form_id
        ]) -> findOrEmpty();

        if ($form -> isEmpty()) return message() -> nodata('请选择模型后进行绑定');

        if ($form['form_bind_model'] !== '-1') return message() -> update_failed('绑定模型失败，已有绑定模型');
        if ($form['form_name'] === $form_name) return message() -> update_failed('绑定模型失败，模型不能绑定自身');

        return message() -> success('绑定模型成功', (new formModel) -> update([
            'form_bind_model' => $form_name
        ], ['form_id' => $form_id]) -> getChangedData());
    }

    /**
     * 添加表单模型列
     * @param formFieldInfo|null $formFieldInfo
     * @return Response
     */
    #[PostMapping]
    #[AuthAnnotation('form', 'formReadWrite|formWrite')]
    public function addField(?formFieldInfo $formFieldInfo = null): Response
    {
        $fromModel = new formModel();
        $form = $fromModel -> getForm($formFieldInfo -> form_id);
        $type = $formFieldInfo -> form_field_type;
        [$formFieldInfo -> form_field_type, $formFieldInfo -> form_field_length ] = array_values($formFieldInfo -> getFormFieldType());
        if ($form) {

            // 验证当前 表单模型字段是否存在
            $formFieldModel = new formFieldModel;
            if ($formFieldModel -> where([
                'form_field_name' => $formFieldInfo -> form_field_name,
                'form_id' => $formFieldInfo -> form_id
            ]) -> findOrEmpty() -> isExists()) return message() -> update_failed("该列名已存在");

            // 生成字段SQL 并执行
            $sql = sprintf(
                    "alter table `%s` ADD COLUMN ex_%s %s%s COMMENT '%s'",
                    $form['form_name'],
                    $formFieldInfo -> form_field_name,
                    $formFieldInfo -> form_field_type,
                    $formFieldInfo -> form_field_length,
                    $formFieldInfo -> form_field_description
                );

            $formFieldModel -> execute($sql);
            // 将字段写入 字段表
            $formFieldInfo -> form_field_name = 'ex_'. $formFieldInfo -> form_field_name;
            $formFieldInfo -> form_field_type = $type;
            return $formFieldModel -> addField($formFieldInfo);
        }
        return message() -> nodata("表模型不存在");
    }

    /**
     * 删除表单模型列
     * @param int $form_id
     * @param string $form_field_name
     * @return Response
     */
    #[DeleteMapping('del_field/<[0-9]{1,8}:form_id>/<[a-zA-z0-9]+:form_field_name>')]
    #[AuthAnnotation('form', 'formReadWrite|formWrite')]
    public function delField(int $form_id = 0, string $form_field_name = ''): Response
    {

        if (!substr($form_field_name, 0, 3) === 'ex_') {
            return message() -> update_failed('删除失败， 默认字段无法删除');
        }

        $form = (new formModel) -> getForm($form_id);

        if ($form['title_field'] === $form_field_name) {
            return message() -> update_failed('删除失败， 该列为标题字段无法删除');
        }

        if ($form) {
            $formFieldModel = new formFieldModel();
            $formFieldModel -> execute("alter table {$form['form_name']} DROP COLUMN {$form_field_name}");
            return $formFieldModel -> deleteData([
                'form_id' => $form_id,
                'form_field_name' => $form_field_name
            ]);
        }
        return message() -> nodata("表模型不存在");
    }

    /**
     * 表单模型添加内容
     * @param formContent|null $formContent
     * @return Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    #[PostMapping]
    #[AuthAnnotation('form', 'formReadWrite|formWrite')]
    public function addFormContent(?formContent $formContent = null): Response {
        $info = $formContent -> getFormContent();
        if ($info instanceof Response) return $info;
        $id = (new buildModel(table: $info -> getForm()['form_name'])) -> insertGetId($info -> create());
        if ($id) {
            $data['id'] = $id;
            return message() -> success('数据新建成功', $data);
        }
        return message() -> update_failed('数据新建失败');
    }

    /**
     * 更新表单模型内容
     * @param formContent|null $formContent
     * @return Response
     * @throws DbException
     */
    #[PostMapping]
    #[AuthAnnotation('form', 'formReadWrite|formWrite')]
    public function updateFormContent(?formContent $formContent = null): Response {

        if (empty($formContent -> content['id']) || !is_numeric($formContent -> content['id'])) {
            return message() -> parameter_error('请选择需要更新的数据模型');
        }

        $info = $formContent -> getFormContent();
        if ($info instanceof Response) return $info;
        if (
            (new buildModel(table: $info -> getForm()['form_name'])) -> where([
                'id' => $formContent -> content['id']
            ]) -> update($info -> getData())
        ) {
            return message() -> success('数据更新成功', $info -> content);
        }
        return message() -> update_failed('数据更新失败');
    }

    /**
     * 删除表单模型内容
     * @param int $form_id
     * @param int $id
     * @return Response
     */
    #[DeleteMapping('del_form_content/<[0-9]{1,8}:form_id>/<[0-9]{1,8}:id>')]
    #[AuthAnnotation('form', 'formReadWrite|formWrite')]
    public function delFormContent(
        int $form_id = 0,
        int $id = 0
    ): Response {
        $form = (new formModel) -> getForm($form_id);
        if ($form === null) return message() -> nodata('表单模型不存在');
        $query = (new buildModel(table: $form['form_name'])) -> where([
            'id' => $id
        ]);
        $info = $query -> findOrEmpty();

        if (!$info) return message() -> update_failed('删除数据失败， 暂无需要删除的数据');

        // 删除评论数据
        replyModel::where([
            'col_uuid' => $info['uuid']
        ]) -> delete();

        // 删除表单数据
        $query -> delete();
        return message() -> success('删除数据成功');
    }
}